package com.gitee.apanlh.util.base;

import com.gitee.apanlh.util.base.enums.CalculationTypeEnum;
import com.gitee.apanlh.util.base.enums.Sort;
import com.gitee.apanlh.util.date.DateUtils;
import com.gitee.apanlh.util.func.FuncCollectionExecute;
import com.gitee.apanlh.util.func.FuncFilter;
import com.gitee.apanlh.util.func.FuncFind;
import com.gitee.apanlh.util.func.FuncFindCall;
import com.gitee.apanlh.util.func.FuncGet;
import com.gitee.apanlh.util.func.FuncGroupBy;
import com.gitee.apanlh.util.func.FuncIteratorResultE;
import com.gitee.apanlh.util.func.FuncPage;
import com.gitee.apanlh.util.reflection.ClassTypeUtils;
import com.gitee.apanlh.util.reflection.ClassUtils;
import com.gitee.apanlh.util.reflection.ReflectionUtils;
import com.gitee.apanlh.util.valid.ValidParam;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.CompletableFuture;
import java.util.function.Function;

/**	
 * 	集合工具类
 * 
 * 	@author Pan
 */
public class CollUtils {
	
	/**
	 * 	构造函数
	 * 	
	 * 	@author Pan
	 */
	private CollUtils() {
		//	不允许外部实例
		super();
	}
	
	/**	
	 * 	添加元素(集合)
	 * 	<br>将集合2添加值集合1中
	 * 	
	 * 	@author Pan
	 * 	@param 	<E>		元素
	 * 	@param 	list	集合
	 * 	@param 	list2	集合2
	 * 	@return	List
	 */
	public static <E> List<E> addAll(List<E> list, List<E> list2) {
		if (list == null || list2 == null) {
			return list;
		}
		list.addAll(list2);
		return list;
	}
	
	/**	
	 * 	添加元素(泛型)
	 * 	
	 * 	@author Pan
	 * 	@param 	<E>			元素
	 * 	@param 	list		集合
	 *	@param 	elements	一个或多个元素
	 * 	@return	List
	 */
	@SafeVarargs
	public static <E> List<E> addAll(List<E> list, E... elements) {
		if (list == null || elements == null) {
			return list;
		}
		Collections.addAll(list, elements);
		return list;
	}
	
	/**	
	 * 	添加元素(Map)
	 * 	
	 * 	@author Pan
	 * 	@param 	<K>			键类型
	 * 	@param 	<V>			值类型
	 * 	@param 	list		集合
	 *	@param 	map			Map
	 * 	@return	List
	 */
	public static <K, V> List<V> addAll(List<V> list, Map<K, V> map) {
		if (list == null || map == null) {
			return list;
		}
		
		list.addAll(map.values());
		return list;
	}
	
	/**	
	 * 	添加元素(Set)
	 * 	
	 * 	@author Pan
	 * 	@param 	<E>			元素
	 * 	@param 	set			集合
	 * 	@param 	elements	一个或多个元素
	 * 	@return	Set
	 */
	@SafeVarargs
	public static <E> Set<E> addAll(Set<E> set, E... elements) {
		if (set == null || elements == null) {
			return set;
		}
		
		Collections.addAll(set, elements);
		return set;
	}
	
	/**
	 * 	Set添加元素(Map)
	 * 	
	 * 	@author Pan
	 * 	@param 	<K>	键类型
	 * 	@param 	<V>	值类型
	 * 	@param 	set	集合
	 * 	@param 	map  Map
	 * 	@return	Set
	 */
	public static <K, V> Set<V> addAll(Set<V> set, Map<K, V> map) {
		if (set == null || map == null) {
			return set;
		}
		
		set.addAll(map.values());
		return set;
	}
	
	/**	
	 * 	Set添加元素(collection)
	 * 	
	 * 	@author Pan
	 * 	@param 	<E>			元素
	 * 	@param 	set			集合
	 * 	@param 	collection	collection集合
	 * 	@return	Set
	 */
	public static <E> Set<E> addAll(Set<E> set, Collection<E> collection) {
		if (set == null || collection == null) {
			return set;
		}
		
		set.addAll(collection);
		return set;
	}
	
	/**	
	 * 	自动分组List
	 * 	<br>对未知分配数做一个均衡
	 * 
	 * 	@author Pan
	 * 	@param 	<T>		数据类型
	 * 	@param 	list	集合
	 * 	@return List
	 */
	public static <T> List<List<T>> averageList(List<T> list) {
		if (isEmpty(list)) {
			return Empty.list();
		}
		
		int listSize = list.size();
		int averageNum = averageNum(listSize);
		//	总数 / 平均数 = 分组数
		return partitionList(list, listSize / averageNum);
	}
	
	/**
	 * 	计算平衡平均分配
	 * 	返回最后一个值
	 * 
	 * 	@author Pan
	 * 	@param 	listSize	集合长度
	 *	@return	int
	 */
	private static int averageNum(int listSize) {
		int score = 0;
		int index = 0;
		int srcLen = 16;
		int [] averageArr = new int[srcLen];
		
		for (;;) {
			if (index >= srcLen) {
				srcLen = srcLen * 2;
				averageArr = ArrayUtils.copy(averageArr, srcLen);
			}
			//	计算
			averageArr[index] = listSize / ++score;
			//	非第一次 && 值等于上一次时停止计算
			if (index != 0 && averageArr[index] == averageArr[index - 1]) {
				//	剔除0
				int findZero = 0;
				//	j > 0 && 找不到0的值终止循环
				for (int j = srcLen - 1; j > 0 && averageArr[j] == 0; j--) {
					findZero ++;
				}
				if (findZero != 0) {
					averageArr = ArrayUtils.copy(averageArr, srcLen - findZero);
				}
				//	终止查找
				break;
			} 
			++index;
		}
		//	返回最后一个平均数值
		return averageArr[averageArr.length - 1];
	}

	/**
	 *  二分查找函数式
	 *  <br>返回索引
	 *	<br>如果未找到返回-1
	 *
	 *  @author Pan
 	 * 	@param 	<E>		 值类型
	 * 	@param 	<C>   	 比较类型
	 * 	@param 	list	 集合
	 * 	@param 	funcGet  数据流
	 * 	@param 	value    值
	 * 	@return int
	 */
	public static <E, C extends Comparable<? super C>> int binarySearch(List<E> list, FuncGet<E, C> funcGet, C value) {
		if (isEmpty(list)) {
			return -1;
		}
		if (value == null) {
			return -1;
		}
		int start = 0;
		int end = list.size() - 1;

		while (start <= end) {
			//	计算出中间索引值
			int middle = (end + start) >>> 1;//防止溢出
			C data = funcGet.get(list.get(middle));

			int comparison = value.compareTo(data);
			if (comparison == 0) {
				return middle;
				//	判断下限
			} else if (comparison < 0) {
				end = middle - 1;
				//	判断上限
			} else {
				start = middle + 1;
			}
		}
		//若没有，则返回-1
		return -1;
	}

	/**
	 * 	对集合进行一个批量处理操作
	 * 	<br>自定义限制长度
	 * 	
	 * 	@author Pan
	 * 	@param 	<T>			数据类型
	 * 	@param 	list		集合
	 * 	@param 	limit		限制长度
	 * 	@param 	pageFunc	分页函数
	 */
	public static <T> void batchProcess(List<T> list, int limit, FuncPage<T> pageFunc) {
		if (CollUtils.isEmpty(list)) {
			return ;
		}
		
		int listSize = list.size();
		int partitionLen = CollUtils.partitionLen(listSize, limit);
		int fromIndex = 0;
		int toIndex = limit;
		
		for (int i = 0; i < partitionLen; i ++) {
			if (listSize < limit || toIndex >= listSize) {
				pageFunc.part(list.subList(fromIndex, listSize));
				break;
			}
			pageFunc.part(list.subList(fromIndex, toIndex));
			fromIndex = toIndex;
			toIndex += limit;
		}
	}
	
	/**	
	 * 	对集合进行一个批量处理操作(异步)
	 * 	<br>自定义限制长度
	 * 	<br>可以用于批量更新/插入等特定异步操作
	 * 	
	 * 	@author Pan
	 * 	@param 	<T>			数据类型
	 * 	@param 	list		集合
	 * 	@param 	limit		限制长度
	 * 	@param 	batchFunc	分页函数
	 */
	public static <T> void batchProcessAsync(List<T> list, int limit, FuncPage<T> batchFunc) {
		if (CollUtils.isEmpty(list)) {
			return ;
		}
		List<List<T>> partitionList = CollUtils.partitionList(list, limit);
		
		for (int i = 0; i < partitionList.size(); i++) {
			List<T> partition = partitionList.get(i);
			CompletableFuture.runAsync(() -> batchFunc.part(partition));
		}
	}
	
	/**	
	 * 	浅克隆
	 * 	
	 * 	@author Pan
	 * 	@param 	<T>		数据类型
	 * 	@param 	list	集合
	 * 	@return	List
	 */
	public static <T> List<T> copy(List<T> list) {
		return newArrayList(list);
	} 
	
	/**
	 * 	数值计算转换匹配类型
	 * 	
	 * 	@author Pan
	 * 	@param 	<T>				数据类型
	 * 	@param 	list			集合
	 * 	@param 	calculationType	计算方式类型
	 * 	@return T
	 */
	@SuppressWarnings("unchecked")
	private static <T> T calculation(List<T> list, CalculationTypeEnum calculationType) {
		T type = list.get(0);
		if (type instanceof String) {
			return (T) calculationTypeStr((List<String>) list, calculationType);
		}
		if (type instanceof Integer) {
			return (T) calculationTypeInt((List<Integer>) list, calculationType);
		}
		if (type instanceof Long) {
			return (T) calculationTypeLong((List<Long>) list, calculationType);
		}
		if (type instanceof Float) {
			return (T) calculationTypeFloat((List<Float>) list, calculationType);
		}
		if (type instanceof Double) {
			return (T) calculationTypeDouble((List<Double>) list, calculationType);
		}
		return null;
	}
	
	/**	
	 * 	String类型匹配计算方式
	 * 	
	 * 	@author Pan
	 * 	@param 	list	集合
	 *  @param 	type	计算方式
	 * 	@return String
	 */
	private static String calculationTypeStr(List<String> list, CalculationTypeEnum type) {
		switch (type) {
			case MAX:
				return Collections.max(list);
			case MIN:
				return Collections.min(list);
			case SUM:
				int size = list.size();
				if (size == 1) {
					return Integer.toString(Integer.parseInt(list.get(0)));
				}
				String count = null;
				for (int i = 0, len = size; i < len; i ++) {
					String value = list.get(i);
					if (!ValidParam.isEmpty(value)) {
						count = Integer.toString(Integer.parseInt(count) + Integer.parseInt(value));
					}
				}
				return count;
			default:
				return null;
		}
	}
	
	/**	
	 * 	Integer类型匹配计算方式
	 * 	
	 * 	@author Pan
	 * 	@param 	list	集合
	 *  @param 	type	计算方式
	 * 	@return Integer
	 */
	private static Integer calculationTypeInt(List<Integer> list, CalculationTypeEnum type) {
		switch (type) {
			case MAX:
				return Collections.max(list);
			case MIN:
				return Collections.min(list);
			case SUM:
				int size = list.size();
				if (size == 1) {
					return list.get(0);
				}
				Integer count = 0;
				for (int i = 0, len = size; i < len; i ++) {
					Integer value = list.get(i);
					if (ValidParam.isNotNull(value)) {
						count = count + value;
					}
				}
				return count;
			default:
				return null;
		}
	}
	
	/**	
	 * 	Long类型匹配计算方式
	 * 	
	 * 	@author Pan
	 * 	@param 	list	集合
	 * 	@param 	type	计算方式
	 * 	@return	Long
	 */
	private static Long calculationTypeLong(List<Long> list, CalculationTypeEnum type) {
		switch (type) {
			case MAX:
				return Collections.max(list);
			case MIN:
				return Collections.min(list);
			case SUM:
				int size = list.size();
				if (size == 1) {
					return list.get(0);
				}
				Long count = 0L;
				for (int i = 0, len = size; i < len; i ++) {
					Long value = list.get(i);
					if (ValidParam.isNotNull(value)) {
						count = count + value;
					}
				}
				return count;
			default:
				return null;
		}
	}
	
	/**	
	 * 	Double类型匹配计算方式
	 * 	
	 * 	@author Pan
	 * 	@param 	list	集合
	 * 	@param 	type	计算方式
	 * 	@return Double
	 */
	private static Double calculationTypeDouble(List<Double> list, CalculationTypeEnum type) {
		switch (type) {
			case MAX:
				return Collections.max(list);
			case MIN:
				return Collections.min(list);
			case SUM:
				int size = list.size();
				if (size == 1) {
					return list.get(0);
				}
				Double count = 0D;
				for (int i = 0, len = size; i < len; i ++) {
					Double value = list.get(i);
					if (ValidParam.isNotNull(value)) {
						count = count + value;
					}
				}
				return count;
			default:
				return null;
		}
	}
	
	/**	
	 * 	Float类型匹配计算方式
	 * 	
	 * 	@author Pan	
	 * 	@param 	list	集合
	 * 	@param 	type	计算方式
	 * 	@return	Float
	 */
	private static Float calculationTypeFloat(List<Float> list, CalculationTypeEnum type) {
		switch (type) {
			case MAX:
				return Collections.max(list);
			case MIN:
				return Collections.min(list);
			case SUM:
				int size = list.size();
				if (size == 1) {
					return list.get(0);
				}
				Float count = 0F;
				for (int i = 0, len = size; i < len; i ++) {
					Float value = list.get(i);
					if (ValidParam.isNotNull(value)) {
						count = count + value;
					}
				}
				return count;
			default:
				return null;
		}
	}
	
	/**
	 * 	去重对象
	 * 	<br>如果数据存在Null则数据移除
	 *
	 * 	@author Pan
	 * 	@param 	<T>  数据类型
	 * 	@param 	list 集合
	 * 	@return	List
	 */
	public static <T> List<T> distinct(final List<T> list) {
		if (CollUtils.isEmpty(list)) {
			return Empty.list();
		}
		return newArrayList(newLinkedHashSet(list));
	}
	
	/**	
	 * 	字段属性去重
	 * 	<br>数据量小或大都可使用 
	 * 	<br>如果数据存在Null则原有数据移除
	 * 	
	 * 	@author Pan
	 * 	@param 	<T>			数据类型
	 * 	@param 	list		集合
	 * 	@param 	fieldName	字段名
	 * 	@return List
	 */
	public static <T> List<T> distinct(List<T> list, String fieldName) {
		if (CollUtils.isEmpty(list)) {
			return Empty.list();
		}

		List<T> list2 = newArrayList();

		MapUtils.newHashMap((Map<Object, T> map) -> {
			Field field = ReflectionUtils.getField(ClassUtils.getClass(list), fieldName);
			
			for (int i = 0, len = list.size(); i < len; i++) {
				T srcObj = list.get(i);
				if (ValidParam.isNotNull(srcObj)) {
					Object srcValue = ReflectionUtils.getFieldValue(field, srcObj);
					//	不为空与不存在时添加，  如果后续值出现重复则只保留第一次存放的值
					if (ValidParam.isNotNull(srcValue) && map.get(srcValue) == null) {
						map.put(srcValue, srcObj);
					} 
				}
			}
			
			if (map.size() > 0) {
				addAll(list2, map);
			}
		}, list.size());
		return list2;
	}
	
	/**	
	 * 	<br>根据自定义字段数据去重
	 * 	<br>如果数据存在Null则原有数据移除
	 * 	<br>LinkedHashSet方式
	 * 
	 * 	@author Pan
	 * 	@param 	<T>			数据类型
	 * 	@param 	<R>			返回类型
	 * 	@param 	list		集合
	 * 	@param 	funcGet		获取数据函数
	 * 	@return	List		
	 */
	public static <T, R> List<R> distinct(List<T> list, FuncGet<T, R> funcGet) {
		return newArrayList(distinctToSet(list, funcGet));
	}
	
	/**	
	 * 	<br>根据自定义字段数据去重
	 * 	<br>LinkedHashSet
	 * 
	 * 	@author Pan
	 * 	@param 	<T>			数据类型
	 * 	@param 	<R>			返回类型
	 * 	@param 	list		集合
	 * 	@param 	funcGet		获取数据函数
	 * 	@return	Set		
	 */
	public static <T, R> Set<R> distinctToSet(List<T> list, FuncGet<T, R> funcGet) {
		if (CollUtils.isEmpty(list)) {
			return Empty.set();
		}
		
		return newLinkedHashSet(newSet -> {
			for (int i = 0; i < list.size(); i++) {
				R r = funcGet.get(list.get(i));
				if (!newSet.contains(r)) {
					newSet.add(r);
				}
			}
		}, list.size());
	}
	
	/**
	 * 	差集-不修改原有对象(返回新对象)
	 * 	<br>假设有集合A和B，所有属于A且不属于B的元素的集合被称为A与B的差集。
	 *	<br>示例：对于集合A = {a, b, c, d}和集合B = {b, c, w}，则A与B的差集为{a, d}
	 *	
	 *	@author Pan
	 *	@param  <E>     元素
	 *	@param 	set		Set集合
	 * 	@param 	set2	Set集合2
	 * 	@return	Set
	 */
	public static <E> Set<E> difference(final Set<E> set, final Set<E> set2) {
		if (isEmpty(set) && isEmpty(set2)) {
			return Empty.set();
		}
		if (set2.containsAll(set)) {
			return Empty.set();
		}

		return IteratorUtils.collectionResult(set, new FuncIteratorResultE<E, Set<E>>() {
			Set<E> hashSet = newHashSet();
			@Override
			public boolean next(E e, Iterator<E> iterator) {
				if (!set2.contains(e)) {
					hashSet.add(e);
				}
				return true;
			}
			@Override
			public Set<E> call() {
				return hashSet;
			}
		});
	}
	
	/**	
	 * 	差集-不修改原有对象(返回新对象)
	 * 	<br>假设有集合A和B，所有属于A且不属于B的元素的集合被称为A与B的差集。
	 *	<br>示例：对于集合A = {a, b, c, d}和集合B = {b, c, w}，则A与B的差集为{a, d}
	 *	
	 * 	@author Pan
	 * 	@param 	<E>		元素
	 * 	@param  list	集合
	 *  @param  list2	集合2
	 * 	@return	Set
	 */
	public static <E> Set<E> difference(final List<E> list, final List<E> list2) {
		return difference(newHashSet(list), newHashSet(list2));
	}
	
	/**
	 * 	比较两个集合是否一致
	 * 	<br>包含模式
	 * 	<br>验证是否全包含元素
	 * 	
	 * 	@author Pan
	 * 	@param 	<E>		元素
	 * 	@param  list	集合1
	 * 	@param  list2	集合2
	 * 	@return	boolean
	 */
	public static <E> boolean eq(Collection<E> list, Collection<E> list2) {
		return eq(list, list2, true);
	}
	
	/**
	 * 	比较两个集合是否一致
	 * 	<br>全匹配模式
	 * 	<br>严格验证顺序，值
	 * 	
	 * 	@author Pan
	 * 	@param 	<E>		元素
	 * 	@param  list	集合1
	 * 	@param  list2	集合2
	 * 	@return	boolean
	 */
	public static <E> boolean eqByOrder(Collection<E> list, Collection<E> list2) {
		return eq(list, list2, false);
	}

	/**
	 * 	比较两个集合是否一致
	 * 	<br>自定义模式
	 * 	<br>true则验证判断包含元素
	 *  <br>false则严格验证顺序，值
	 *  
	 * 	@author Pan
	 * 	@param  list			集合1
	 * 	@param  list2			集合2
	 * 	@param  equalsMode		如果为true则验证判断包含，false则严格验证顺序，值
	 * 	@return	boolean
	 */
	private static <E> boolean eq(Collection<E> list, Collection<E> list2, boolean equalsMode) {
		//	如果两个都为null视为true
		if (list == null && list2 == null) {
			return true;
		}
		
		if (list == null  	  || 
			list2 == null 	  || 
			list.size() != list2.size()) {
			return false;
		}
		
		//	包含匹配模式
		if (equalsMode) {
			return list.containsAll(list2);
		}
		
		Iterator<E> iterator = list.iterator();
		Iterator<E> iterator2 = list2.iterator();
		
		while (iterator.hasNext()) {
			if (!ObjectUtils.eq(iterator.next(), iterator2.next())) {
				return false;
			}
		}
		return true;
	}
	
	/**	
	 * 	过滤数据(在原集合基础上)
	 * 	
	 * 	@author Pan
	 * 	@param 	<E>		元素
	 * 	@param 	list	原集合
	 * 	@param 	element	过滤元素
	 */
	public static <E> void filter(List<E> list, Object element) {
		if (isEmpty(list)) {
			return ;
		}
		
		IteratorUtils.collection(list, (e, iterator) -> {
			if (ObjectUtils.eq(e, element)) {
				iterator.remove();
			}
		});
	}
	
	/**
	 * 	过滤数据(在原集合基础上)
	 * 	
	 * 	@author Pan
	 * 	@param 	<E>			元素
	 * 	@param 	list		原集合
	 * 	@param 	collection	过滤集合
	 */
	public static <E> void filter(List<E> list, Collection<E> collection) {
		if (isEmpty(list)) {
			return ;
		}
		list.removeAll(collection);
	}
	
	/**
	 * 	过滤数据(在原集合基础上)
	 * 	
	 * 	@author Pan
	 * 	@param 	<E>		元素
	 * 	@param 	list		集合
	 * 	@param 	filter	自定义过滤条件
	 */
	public static <E> void filter(List<E> list, FuncFilter<E> filter) {
		if (isEmpty(list)) {
			return ;
		}
		filter((Collection<E>) list, filter);
	}
	
	/**
	 * 	过滤数据(在原集合基础上)
	 * 	
	 * 	@author Pan
	 * 	@param 	<E>			元素
	 * 	@param 	collection	集合
	 * 	@param 	element		需要被过滤的数据
	 */
	public static <E> void filter(Collection<E> collection, Object element) {
		if (isEmpty(collection)) {
			return ;
		}
		
		IteratorUtils.collection(collection, (e, iterator) -> {
			if (ObjectUtils.eq(e, element)) {
				iterator.remove();
			}
		});
	}
	
	/**
	 * 	过滤数据(在原集合基础上)
	 * 	
	 * 	@author Pan
	 * 	@param 	<E>			元素
	 * 	@param 	collection	集合
	 * 	@param 	filter		自定义过滤条件
	 */
	public static <E> void filter(Collection<E> collection, FuncFilter<E> filter) {
		if (isEmpty(collection)) {
			return ;
		}
		
		IteratorUtils.collection(collection, (e, iterator) -> {
			if (filter.accept(e)) {
				iterator.remove();
			}
		});
	}
	
	/**	
	 * 	搜索第一次匹配返回
	 * 	
	 * 	@author Pan
	 * 	@param 	<T>			数据类型
	 * 	@param 	list		集合
	 * 	@param 	element		元素
	 * 	@return	T
	 */
	public static <T> T findOne(Collection<T> list, Object element) {
		if (isEmpty(list)) {
			return null;
		}
		
		Iterator<T> iterator = IteratorUtils.collection(list);
		while (iterator.hasNext()) {
			T next = iterator.next();
			if (ObjectUtils.eq(next, element)) {
				return next;
			}
		}
		return null;
	}
	
	/**	
	 * 	搜索第一次匹配返回
	 * 	
	 * 	@author Pan
	 * 	@param 	<T>			数据类型
	 * 	@param 	list		集合
	 * 	@param 	funcFind	搜索函数
	 * 	@return	T
	 */
	public static <T> T findOne(Collection<T> list, FuncFind<T> funcFind) {
		if (isEmpty(list)) {
			return null;
		}

		return IteratorUtils.collectionResult(list, new FuncIteratorResultE<T, T>() {
			T result = null;
			@Override
			public boolean next(T e, Iterator<T> iterator) {
				if (funcFind.accept(e)) {
					result = e;
					return false;
				}
				return true;
			}
			@Override
			public T call() {
				return result;
			}
		});
	}
	
	/**
	 * 	根据查询值
	 * 	<br>找到某一条或多条匹配数据
	 * 	
	 * 	@author Pan
	 * 	@param 	list			集合
	 * 	@param 	searchValue		搜索值
	 * 	@return	List
	 */
	public static List<Object> find(List<Object> list, Object searchValue) {
		return findCall(list, t -> ObjectUtils.eq(t, searchValue) ? t : null);
	}
	
	/**
	 * 	从中找到某一条匹配数据
	 * 	<br>根据条件找到一条或者多条的匹配数据
	 * 
	 * 	@author Pan
	 * 	@param 	<T>				数据类型
	 * 	@param 	<E>				元素
	 * 	@param 	list			集合
	 * 	@param 	searchKey  		对象值字段名
	 * 	@param 	searchValue 	搜索值
	 * 	@return	List			一个或多个匹配值
	 */
	public static <T, E> List<T> find(List<T> list, String searchKey, E searchValue) {
		if (isEmpty(list)) {
			return Empty.list();
		}
		
		Field filed = ReflectionUtils.getField(ClassUtils.getClass(list), searchKey);
		return findCall(list, t -> ObjectUtils.eq(ReflectionUtils.getFieldValue(filed, t), searchValue) ? t : null);
	}
	
	/**
	 * 	根据自定义条件搜索数据
	 * 	<br>实现accept方法进行条件筛选
	 * 	<br>条件返回true则筛选成功
	 * 	
	 * 	@author Pan
	 * 	@param 	<E>			元素
	 * 	@param 	list		集合
	 * 	@param 	findFunc	筛选方法
	 * 	@return	List
	 */
	public static <E> List<E> find(Collection<E> list, FuncFind<E> findFunc) {
		if (isEmpty(list)) {
			return Empty.list();
		}
		
		List<E> findList = newArrayList();
		IteratorUtils.collection(list, (e, iterator) -> {
			if (findFunc.accept(e)) {
				findList.add(e);
			}
		});
		return findList;
	}
	
	/**	
	 * 	根据自定义条件搜索数据
	 * 	<br>与find方法不同的是: find只能返回本身已有的值, findCall方法能返回自定义值(类型一致即可)
	 * 	<br>返回自定义值
	 * 	<br>例如list = {"1", "2", "2"} t.equals("2") return "11" 此时将返回两条 ["11", "11"]数据
	 * 	<br>条件返回true则筛选成功
	 * 
	 * 	@author Pan
	 * 	@param 	<E>			元素
	 * 	@param 	list		集合
	 * 	@param 	findCall	筛选方法
	 * 	@return	List
	 */
	public static <E> List<E> findCall(Collection<E> list, FuncFindCall<E> findCall) {
		return IteratorUtils.collectionResult(list, new FuncIteratorResultE<E, List<E>>() {
			private List<E> findList = null;
			@Override
			public boolean next(E e, Iterator<E> iterator) {
				E accept = findCall.accept(e);
				if (ValidParam.isNotNull(accept)) {
					if (findList == null) {
						findList = newArrayList();
					}
					findList.add(accept);
				}
				return true;
			}
			@Override
			public List<E> call() {
				return findList;
			}
		});
	}
	
	/**
	 * 	返回首次不为null的数据
	 * 	
	 * 	@author Pan
	 * 	@param 	<T>		数据类型
	 * 	@param 	<R>		返回类型
	 * 	@param 	list	集合
	 * 	@param 	funcGet	获取函数
	 * 	@return R
	 */
	public static <T, R> R findFirstNotNull(List<T> list, FuncGet<T, R> funcGet) {
		if (isEmpty(list)) {
			return null;
		}
		
		for (int i = 0; i < list.size(); i++) {
			R r = funcGet.get(list.get(i));
			if (ValidParam.isNotNull(r)) {
				return r;
			}
		}
		return null;
	}
	
	/**
	 * 	根据自定义条件进行分组
	 * 	<br>key		=	组名
	 *  <br>value	=	值
	 *  <br>HashMap
	 *  
	 *  @author Pan
	 *  @param 	<K>				键类型
	 * 	@param 	<E>				元素类型
	 * 	@param 	list			集合
	 * 	@param 	funcGroupBy		分组函数
	 * 	@return	Map
	 */
	public static <K, E> Map<K, List<E>> groupBy(List<E> list, FuncGroupBy<E, K> funcGroupBy) {
		if (isEmpty(list)) {
			return Empty.map();
		}
		return MapUtils.newHashMap(newMap -> groupBy(newMap, list, funcGroupBy), list.size());
	}
	
	/**
	 * 	根据自定义条件进行分组
	 * 	<br>key		=	组名
	 *  <br>value	=	值
	 *  <br>LinkedHashMap
	 *  
	 *  @author Pan
	 *  @param 	<K>				键类型
	 * 	@param 	<E>				元素类型
	 * 	@param 	list			集合
	 * 	@param 	funcGroupBy		分组函数
	 * 	@return	Map
	 */
	public static <K, E> Map<K, List<E>> groupByToLinked(List<E> list, FuncGroupBy<E, K> funcGroupBy) {
		if (isEmpty(list)) {
			return Empty.map();
		}
		return MapUtils.newLinkedHashMap(newMap -> groupBy(newMap, list, funcGroupBy), list.size());
	}
	
	/**
	 * 	根据自定义条件进行分组
	 * 	<br>key		=	组名
	 *  <br>value	=	值
	 *  <br>CurrentHashMap
	 *  
	 *  @author Pan
	 *  @param 	<K>				键类型
	 * 	@param 	<E>				元素类型
	 * 	@param 	list			集合
	 * 	@param 	funcGroupBy		分组函数
	 * 	@return	Map
	 */
	public static <K, E> Map<K, List<E>> groupByToConcurrent(List<E> list, FuncGroupBy<E, K> funcGroupBy) {
		if (isEmpty(list)) {
			return Empty.map();
		}
		return MapUtils.newConcurrentHashMap(newMap -> groupBy(newMap, list, funcGroupBy), list.size());
	}

	/**
	 * 	分组函数
	 *
	 *  @author Pan
	 *  @param 	<K>				键类型
	 * 	@param 	<E>				元素类型
	 * 	@param 	list			集合
	 * 	@param 	funcGroupBy		分组函数
	 */
	private static <K, E> void groupBy(Map<K, List<E>> map, List<E> list, FuncGroupBy<E, K> funcGroupBy) {
		IteratorUtils.collection(list, (e, iterator) -> {
			K key = funcGroupBy.groupBy(e);
			if (key == null) {
				return ;
			}
			List<E> computeIfAbsent = map.computeIfAbsent(key, o -> newArrayList());
			computeIfAbsent.add(e);
		});
	}

	/**
	 *  indexOf函数式
	 *  <br>返回索引
	 *	<br>如果未找到返回-1
	 *
	 * 	@param 	<E>		 值类型
	 * 	@param 	list	 集合
	 * 	@param 	funcFind 寻找函数
	 * 	@return int
	 */
	public static <E> int indexOf(List<E> list, FuncFind<E> funcFind) {
		if (isEmpty(list)) {
			return -1;
		}

		for (int i = 0, len = list.size(); i < len; i++) {
			if (funcFind.accept(list.get(i))) {
				return i;
			}
		}
		return -1;
	}

	/**
	 *  判断是否当前为最后一个索引
	 *
	 *	@author Pan
	 * 	@param 	<E>		 数据类型
	 * 	@param 	list	 集合
	 * 	@param 	nowIndex 当前索引
	 * 	@return boolean  true当前最后一个
	 */
	public static <E> boolean isLastIndex(List<E> list, int nowIndex) {
		return list.size() -1 == nowIndex;
	}

	/**
	 * 	交集-不修改原有对象(返回新对象)
	 * 	<br>所有属于集合A且属于集合B的元素所组成的集合
	 * 	<br>E1 = {a, b, c ,d} E2 = {b, c} E1∩E2 = {b, c}
	 * 	
	 * 	@author Pan
	 * 	@param 	<E>		元素
	 * 	@param 	e1		集合1
	 * 	@param 	e2		集合2
	 * 	@return	Set
	 */
	public static <E> Set<E> intersection(List<E> e1, List<E> e2) {
		return intersection(newHashSet(e1), newHashSet(e2));
	}
	
	/**	
	 * 	交集-不修改原有对象(返回新对象)
	 * 	
	 * 	<br>所有属于集合A且属于集合B的元素所组成的集合
	 * 	<br>E1 = {a, b, c ,d} E2 = {b, c} E1∩E2 = {b, c}
	 * 	
	 * 	@author Pan
	 * 	@param 	<E>		元素
	 * 	@param 	e1		集合1
	 * 	@param 	e2		集合2
	 * 	@return	Set
	 */
	public static <E> Set<E> intersection(Set<E> e1, Set<E> e2) {
		if ((isEmpty(e1) && isEmpty(e2))) {
			return Empty.set();
		}
		return IteratorUtils.collectionResult(e1, new FuncIteratorResultE<E, Set<E>>() {
			Set<E> hashSet = newHashSet();
			@Override
			public boolean next(E e, Iterator<E> iterator) {
				if (e2.contains(e)) {
					hashSet.add(e);
				}
				return true;
			}
			@Override
			public Set<E> call() {
				return hashSet;
			}
		});
	}
	
	/**	
	 * 	判空
	 * 	
	 * 	@author Pan
	 * 	@param 	<E>				元素
	 * 	@param 	collection		集合
	 * 	@return boolean			true为空  false为 非空
	 */
	public static <E> boolean isEmpty(Collection<E> collection) {
		return null == collection || collection.isEmpty();
	}
	
	/**
	 * 	寻找最大值
	 * 	<br>支持String, Integer, Long, Double, Float类型
	 * 	
	 * 	@author Pan
	 * 	@param 	<E>		元素
	 * 	@param 	list	集合
	 * 	@return	E
	 */
	public static <E> E max(List<E> list) {
		if (isEmpty(list)) {
			return null;
		}
		return calculation(list, CalculationTypeEnum.MAX);
	} 
	
	/**	
	 * 	寻找最大值
	 * 	<br>支持String, Integer, Long, Double, Float类型
	 * 	
	 * 	@author Pan
	 * 	@param 	<E>			元素
	 * 	@param 	list		集合
	 * 	@param 	fieldName	字段名称
	 * 	@return	Object
	 */
	public static <E> Object max(List<E> list, String fieldName) {
		if (isEmpty(list)) {
			return null;
		}
		return max(ReflectionUtils.getFieldValue(list, fieldName));
	}

	/**
	 *	寻找最大值
	 * 	<br>支持String, Integer, Long, Double, Float类型
	 *
	 * 	@param  <T>		数据类型
	 * 	@param  <R>		返回类型
	 *	@param  list	集合
	 * 	@param  funcGet	函数
	 * 	@return R 找到的最大值
	 */
	public static <T, R> R max(List<T> list, FuncGet<T, R> funcGet) {
		R max = null;

		for (int i = 0; i < list.size(); i++ ) {
			R t = funcGet.get(list.get(i));

			if (t == null) {
				continue;
			}
			if (max == null) {
				max = t;
			}
			if (t instanceof String && t.hashCode() > max.hashCode()) {
				max = t;
			}
			if (t instanceof Number) {
				Comparable<R> tc = (Comparable<R>) t;
				if (tc.compareTo(max) > 0) {
					max = t;
				}
			}
		}
		return max;
	}

	/**
	 *  lastIndexOf函数式
	 *	<br>返回索引
	 *	<br>如果未找到返回-1
	 *
	 * 	@param 	<E>		 值类型
	 * 	@param 	list	 集合
	 * 	@param 	funcFind 寻找函数
	 * 	@return int
	 */
	public static <E> int lastIndexOf(List<E> list, FuncFind<E> funcFind) {
		if (isEmpty(list)) {
			return -1;
		}

		for (int i = list.size() - 1; i > 0; i--) {
			if (funcFind.accept(list.get(i))) {
				return i;
			}
		}
		return -1;
	}

	/**
	 * 	寻找最小值
	 * 	<br>支持String, Integer, Long, Double, Float类型
	 * 	
	 * 	@author Pan
	 * 	@param 	<E>		元素
	 * 	@param 	list	集合
	 * 	@return	E
	 */
	public static <E> E min(List<E> list) {
		if (isEmpty(list)) {
			return null;
		}
		return calculation(list, CalculationTypeEnum.MIN);
	}

	/**
	 *	寻找最小值
	 * 	<br>支持String, Integer, Long, Double, Float类型
	 *
	 * 	@param  <T>		数据类型
	 * 	@param  <R>		返回类型
	 *	@param  list	集合
	 * 	@param  funcGet	函数
	 * 	@return R 找到的最大值
	 */
	public static <T, R> R min(List<T> list, FuncGet<T, R> funcGet) {
		R min = null;

		for (int i = 0; i < list.size(); i++ ) {
			R t = funcGet.get(list.get(i));
			if (min == null) {
				min = t;
				if (min == null) {
					continue;
				}
			}

			if (t instanceof String && t.hashCode() < min.hashCode()) {
				min = t;
			}
			if (t instanceof Number) {
				Comparable<R> tc = (Comparable<R>) t;
				if (tc.compareTo(min) < 0) {
					min = t;
				}
			}
		}
		return min;
	}

	/**
	 * 	寻找最小值
	 * 	<br>支持String, Integer, Long, Double, Float类型
	 * 	
	 * 	@author Pan
	 * 	@param 	<E>			元素
	 * 	@param 	list		集合
	 * 	@param 	fieldName	字段名
	 * 	@return	E
	 */
	public static <E> Object min(List<E> list, String fieldName) {
		if (isEmpty(list)) {
			return null;
		}
		return min(ReflectionUtils.getFieldValue(list, fieldName));
	} 
	
	/**
	 * 	构建ArrayList
	 * 	
	 * 	@author Pan
	 * 	@param 	<E>	元素
	 * 	@return	List
	 */
	public static <E> List<E> newArrayList() {
		return newArrayList(10);
	}
	
	/**	
	 * 	构建ArrayList
	 * 	
	 * 	@author Pan
	 * 	@param 	<E>				元素
	 * 	@param 	initialCapacity	初始化容量
	 * 	@return	List
	 */
	public static <E> List<E> newArrayList(int initialCapacity) {
		return new ArrayList<>(initialCapacity <= 0 ? 10 : initialCapacity);
	}
	
	/**	
	 * 	构建ArrayList(自定义元素)
	 * 	
	 * 	@author Pan
	 * 	@param 	<E>			元素
	 * 	@param 	elements	添加元素
	 * 	@return	List
	 */
	@SafeVarargs
	public static <E> List<E> newArrayList(E... elements) {
		return addAll(newArrayList(elements.length), elements);
	}
	
	/**	
	 * 	构建ArrayList(集合)
	 * 	
	 * 	@author Pan
	 * 	@param 	<E>			元素
	 * 	@param 	collection	集合
	 * 	@return	List
	 */
	public static <E> List<E> newArrayList(Collection<E> collection) {
		if (isEmpty(collection)) {
			return newArrayList();
		}
		return new ArrayList<>(collection);
	}
	
	/**	
	 * 	构建ArrayList
	 * 	
	 * 	@author Pan
	 * 	@param 	<E>			元素
	 * 	@param 	enumeration	枚举
	 * 	@return	List
	 */
	public static <E> List<E> newArrayList(Enumeration<E> enumeration) {
		List<E> list = newArrayList(10);
		while (enumeration.hasMoreElements()) {
			list.add(enumeration.nextElement());
		}
		return list;
	}
	
	/**	
	 * 	将Map构建ArrayList(返回Map的Value值)
	 * 	
	 * 	@author Pan
	 * 	@param 	<K>		键类型
	 * 	@param 	<V>		值类型
	 * 	@param 	map		Map
	 * 	@return	List
	 */
	public static <K, V> List<V> newArrayList(Map<K, V> map) {
		return new ArrayList<>(map.values());
	}
	
	/**	
	 * 	自定义构建ArrayList
	 * 	
	 * 	@author Pan
	 * 	@param 	<E>		元素
	 * 	@param 	func	初始化函数
	 * 	@return	List
	 */
	public static <E> List<E> newArrayList(FuncCollectionExecute<E> func) {
		return newArrayList(func, 10);
	}
	
	/**	
	 * 	自定义构建ArrayList
	 * 	
	 * 	@author Pan
	 * 	@param 	<E>				元素
	 * 	@param 	func			初始化函数
	 * 	@param 	initialCapacity	初始化容量
	 * 	@return	List
	 */
	public static <E> List<E> newArrayList(FuncCollectionExecute<E> func, int initialCapacity) {
		List<E> list = newArrayList(initialCapacity);
		func.execute(list);
		return list;
	}
	
	/**	
	 * 	构建LinkedList
	 * 	
	 * 	@author Pan
	 * 	@param 	<E>			元素
	 * 	@return	List
	 */
	public static <E> List<E> newLinkedList() {
		return new LinkedList<E>();
	}
	
	/**	
	 * 	构建newLinkedList(自定义元素)
	 * 	
	 * 	@author Pan
	 * 	@param 	<E>			元素
	 * 	@param 	elements	添加元素
	 * 	@return	List
	 */
	@SafeVarargs
	public static <E> List<E> newLinkedList(E... elements) {
		return addAll(newLinkedList(), elements);
	}
	
	/**	
	 * 	构建newLinkedList(集合)
	 * 	
	 * 	@author Pan
	 * 	@param 	<E>			元素
	 * 	@param 	collection	集合
	 * 	@return	List
	 */
	public static <E> List<E> newLinkedList(Collection<E> collection) {
		if (isEmpty(collection)) {
			return newLinkedList();
		}
		return new LinkedList<>(collection);
	}
	
	/**	
	 * 	将Map构建ArrayList(返回Map的Value值)
	 * 	
	 * 	@author Pan
	 * 	@param 	<K>		键类型
	 * 	@param 	<V>		值类型
	 * 	@param 	map		Map
	 * 	@return	List
	 */
	public static <K, V> List<V> newLinkedList(Map<K, V> map) {
		return new LinkedList<>(map.values());
	}
	
	/**	
	 * 	构建LinkedHashSet
	 * 	
	 * 	@author Pan
	 * 	@param 	<E>		元素
	 * 	@return Set
	 */
	public static <E> Set<E> newLinkedHashSet() {
		return newLinkedHashSet(16);
	}
	
	/**	
	 * 	自定义构建newLinkedHashSet
	 * 	
	 * 	@author Pan
	 * 	@param 	<E>		元素
	 * 	@param 	func	初始化函数
	 * 	@return	Set
	 */
	public static <E> Set<E> newLinkedHashSet(FuncCollectionExecute<E> func) {
		return newLinkedHashSet(func, 10);
	}
	
	/**	
	 * 	自定义构建newLinkedHashSet
	 * 	
	 * 	@author Pan
	 * 	@param 	<E>				元素
	 * 	@param 	func			初始化函数
	 * 	@param 	initialCapacity	初始化容量
	 * 	@return	Set
	 */
	public static <E> Set<E> newLinkedHashSet(FuncCollectionExecute<E> func, int initialCapacity) {
		Set<E> set = newLinkedHashSet(initialCapacity);
		func.execute(set);
		return set;
	}
	
	/**	
	 * 	构建LinkedHashSet(自定义元素)
	 * 	
	 * 	@author Pan
	 * 	@param 	<E>			元素
	 * 	@param 	elements	元素
	 * 	@return	Set
	 */
	@SafeVarargs
	public static <E> Set<E> newLinkedHashSet(E... elements) {
		return addAll(newLinkedHashSet(elements.length), elements);
	}
	
	/**	
	 * 	构建LinkedHashSet(集合)
	 * 	
	 * 	@author Pan
	 * 	@param 	<E>			元素
	 * 	@param 	collection	集合
	 * 	@return	Set
	 */
	public static <E> Set<E> newLinkedHashSet(Collection<E> collection) {
		if (isEmpty(collection)) {
			return newLinkedHashSet();
		}
		return new LinkedHashSet<>(collection);
	}
	
	/**	
	 * 	构建LinkedHashSet
	 * 	
	 * 	@author Pan
	 * 	@param 	<E>				元素
	 * 	@param 	initialCapacity	初始化容量
	 * 	@return	Set
	 */
	public static <E> Set<E> newLinkedHashSet(int initialCapacity) {
		return new LinkedHashSet<>(initialCapacity <= 0 ? 16 : initialCapacity);
	}
	
	/**	
	 * 	构建HashSet
	 * 	
	 * 	@author Pan
	 * 	@param 	<E>		元素
	 * 	@return Set
	 */
	public static <E> Set<E> newHashSet() {
		return newHashSet(16);
	}
	
	/**	
	 * 	构建HashSet
	 * 	
	 * 	@author Pan
	 * 	@param 	<E>		元素
	 * 	@param 	initialCapacity	初始化容量
	 * 	@return Set
	 */ 
	public static <E> Set<E> newHashSet(int initialCapacity) {
		return new HashSet<>(initialCapacity <= 0 ? 16 : initialCapacity);
	}
	
	/**	
	 * 	构建HashSet(自定义元素)
	 * 	
	 * 	@author Pan
	 * 	@param 	<E>		元素
	 * 	@param 	elements	元素
	 * 	@return Set
	 */
	@SafeVarargs
	public static <E> Set<E> newHashSet(E... elements) {
		return addAll(newHashSet(elements.length), elements);
	}
	
	/**	
	 * 	构建HashSet(集合)
	 * 	
	 * 	@author Pan
	 * 	@param 	<E>			元素
	 * 	@param 	collection	集合
	 * 	@return	Set
	 */
	public static <E> Set<E> newHashSet(Collection<E> collection) {
		if (isEmpty(collection)) {
			return newHashSet();
		}
		return new HashSet<>(collection);
	}
	
	/**
	 * 	计算集合分段长度
	 * 	
	 * 	@author Pan
	 * 	@param 	totalCount		长度总数
	 * 	@param 	piecewiseNumber	分段数
	 * 	@return	int 			返回的是分段后的长度
	 */
	public static int partitionLen(int totalCount, int piecewiseNumber) {
		return totalCount % piecewiseNumber != 0 ? (totalCount / piecewiseNumber) + 1 : totalCount / piecewiseNumber;
	}
	
	/**
	 * 	将集合按照指定限制长度进行分段切割
	 * 	
	 * 	@author Pan
	 * 	@param 	<T>		数据类型
	 * 	@param 	list	集合
	 * 	@param 	limit	限制长度
	 * 	@return	List		
	 */
	public static <T> List<List<T>> partitionList(List<T> list, int limit) {
		if (ValidParam.isEmpty(list)) {
			return Empty.list();
		}

		if (limit <= 0) {
			limit = 0;
		}
		
		int listSize = list.size();
		//	所需分段长度
		int partListLen = partitionLen(listSize, limit);
		List<List<T>> parttionList = newArrayList(partListLen);
		if (listSize < limit) {
			return addAll(parttionList, list);
		}
		
		int fromIndex = 0;
		int toIndex = limit;
		//	添加分段
		for (int i = 0; i < partListLen; i++) {
			if (toIndex >= listSize) {
				parttionList.add(list.subList(fromIndex, listSize));
				break;
			}
			parttionList.add(list.subList(fromIndex, toIndex));
			fromIndex += limit;
			toIndex += limit;
		}
		return parttionList;
	} 

	/**	
	 * 	List 反转
	 * 	
	 * 	@author Pan
	 * 	@param 	<E>			元素
	 * 	@param 	collection	集合
	 */
	public static <E> void reverse(List<E> collection) {
		Collections.reverse(collection);
	}
	
	/**
	 * 	数组转换List
	 * 	
	 * 	@author Pan
	 * 	@param 	<T>		数据类型
	 * 	@param 	array	数组
	 * 	@return	List
	 */
	public static <T> List<T> toList(T[] array) {
		return Arrays.asList(array);
	}
	
	/**	
	 * 	将集合中的某属性转化至List
	 * 
	 * 	@author Pan
	 * 	@param 	<T>		数据类型
	 * 	@param 	<R>		返回类型
	 * 	@param 	list	集合
	 * 	@param 	funcGet	获取函数
	 * 	@return List
	 */
	public static <T, R> List<R> toList(List<T> list, FuncGet<T, R> funcGet) {
		if (isEmpty(list)) {
			return Empty.list();
		}
		return CollUtils.newArrayList(newList -> IteratorUtils.array(list, t -> newList.add(funcGet.get(t))), list.size());
	}
	
	/**	
	 * 	String转换成{@code List<String>}
	 * 
	 * 	@author Pan
	 * 	@param 	str	字符串
	 * 	@param 	tag	中间的分割字符	一般情况下是逗号		,
	 * 	@return	List
	 */
	public static List<String> toList(String str, String tag) {
		List<String> list = CollUtils.newArrayList();
		char[] charArray = str.toCharArray();

		//	开始标识长度
		int startLen = 0;
		int endLen = 0;
		//	是否为最后一个的标识
		boolean lastFlag = false;
		int charsLen = charArray.length;
		for (int i = 0; i < charsLen; i++) {
			char c = charArray[i];
			
			if (i == (charsLen - 1)) {
				//	如果为最后一个字符时 更变为 开始字符 到最后一个长度
				lastFlag = true;
				endLen = charsLen;
			} else {
				endLen = i;
			}
			
			if (c == tag.charAt(0) || lastFlag) {
				int tempLen = (endLen - startLen);
				char[] tempChars = new char[tempLen];
				int nextVal = startLen;
				
				for (int temp = 0; temp < endLen - startLen; temp++) {
					char tempChar = charArray[nextVal];
					tempChars[temp] = tempChar;
					nextVal += 1;
				}
				
				list.add(new String(tempChars));
				startLen = i + 1;
			}
		}
		return list;
	}
	
	/**
	 * 	通用sort
	 * 	<br>String类型则比较eq方法
	 * 	<br>其他类型则使用BigDecimal进行比较
	 *  <br>例如:{@code CollUtils.sort(list, TestBean::getName, Sort.ASC)}
	 *  
	 *	@author Pan 		
	 * 	@param 	<T>			数据类型
	 * 	@param 	<U>			返回类型
	 * 	@param 	list		集合
	 * 	@param 	func		排序函数
	 * 	@param 	sort		排序类型
	 */
	public static <T, U> void sort(List<T> list,  Function<? super T, ? extends U> func, Sort sort) {
		Collections.sort(list, (o1, o2) -> {
			U apply = func.apply(o1);
			U apply2 = func.apply(o2);
			
			if (apply == null || apply2 == null) {
				return -1;
			}
			List<Object> compareList = CollComparator.setCompareList(apply, apply2);
			Object value1 = compareList.get(0);
			Object value2 = compareList.get(1);
			
			//	如果为字符串则比较equals
			if (ClassTypeUtils.isString(value1)) {
				return CollUtils.isEmpty(compareList) ? -1 : ((String) value1).compareTo((String) value2);
			}
			
			//	其他类型进行比较
			return CollUtils.isEmpty(compareList) ? -1 : BigDecimalUtils.compare(value1, value2);
		});
		sortType(list, sort);
	}	
	
	/**
	 * 	基本数据类型及String类型排序
	 * 	
	 * 	@author Pan
	 * 	@param 	<T>			数据类型
	 * 	@param 	list		集合
	 * 	@param 	sort		排序类型
	 */
	public static <T> void sortBasic(List<T> list, Sort sort) {
		if (isEmpty(list)) {
			return ;
		}
		Class<?> clazz = ClassUtils.getClass(list);
		//	类型检测(非基本数据类型或String类型时不进行排序)
		if (!ClassTypeUtils.isBasicDataType(clazz) || !ClassTypeUtils.isString(clazz)) {
			return ;	
		}
		
		Collections.sort(list, CollComparator.BASIC_COMPARATOR);
		sortType(list, sort);
	}
	
	/**	
	 * 	String类型-升序排序
	 * 	
	 * 	@author Pan
	 * 	@param 	<T>			数据类型
	 * 	@param 	list		集合
	 * 	@param 	fieldName	字段名
	 */
	public static <T> void sortStr(List<T> list, String fieldName) {
		sortStr(list, fieldName, Sort.ASC);
	}
	
	/**	
	 * 	String类型排序
	 * 	
	 * 	@author Pan
	 * 	@param 	<T>			数据类型
	 * 	@param 	list		集合
	 * 	@param 	fieldName	字段名
	 * 	@param 	sort		降序desc 升序asc
	 */
	public static <T> void sortStr(List<T> list, String fieldName, Sort sort) {
		if (CollUtils.isEmpty(list)) {
			return ;
		}
		
		Collections.sort(list, (o1, o2) -> {
			List<String> listCompare = CollComparator.getCompareObj(CollComparator.setCompareList(o1, o2), fieldName);
			return CollUtils.isEmpty(listCompare) ? -1 : listCompare.get(0).compareTo(listCompare.get(1));
		});
		sortType(list, sort);
	}
	
	/**	
	 * 	数字类型-升序排序
	 * 	<br>类型String Integer Double Long 等
	 * 	
	 * 	@author Pan
	 * 	@param 	<T>				数据类型
	 * 	@param 	list		集合
	 * 	@param 	fieldName	字段名
	 */
	public static <T> void sortNumber(List<T> list, String fieldName) {
		sortNumber(list, fieldName, Sort.ASC);
	}
	
	/**	
	 * 	数字排序
	 * 	<br>类型String Integer Double Long 等
	 * 	
	 * 	@author Pan
	 * 	@param 	<T>			数据类型
	 * 	@param 	list		需要排序的list
	 * 	@param 	fieldName	字段名
	 * 	@param 	sort		降序desc 升序asc
	 */
	public static <T> void sortNumber(List<T> list, String fieldName, Sort sort) {
		if (CollUtils.isEmpty(list)) {
			return ;
		}
		
		Collections.sort(list, (o1, o2) -> {
			List<String> listCompare = CollComparator.getCompareObj(CollComparator.setCompareList(o1, o2), fieldName);
			return CollUtils.isEmpty(listCompare) ? -1 : BigDecimalUtils.compare(listCompare.get(0), listCompare.get(1));
		});
		sortType(list, sort);
	}
	
	/**
	 * 	时间类型-升序排序
	 * 
	 * 	<br>支持格式为: 
	 * 	<br>yyyy-MM-dd HH:mm:ss
	 * 	<br>yyyy/MM/dd HH:mm:ss
	 * 	<br>yyyyMMddHHmmss
	 * 	<br>yyyy-MM-dd
	 * 	<br>yyyy/MM/dd
	 * 	<br>yyyyMMdd
	 * 	
	 * 	@author Pan
	 * 	@param 	<T>			数据类型
	 * 	@param 	list		集合
	 * 	@param 	fieldName	需要排序的字段名称
	 */
	public static <T> void sortTime(List<T> list, String fieldName) {
		sortTime(list, fieldName, Sort.ASC);
	}
	
	/**
	 * 	时间类型-降序或升序
	 * 	
	 * 	<br>支持格式为: 
	 * 	<br>yyyy-MM-dd HH:mm:ss
	 * 	<br>yyyy/MM/dd HH:mm:ss
	 * 	<br>yyyyMMddHHmmss
	 * 	<br>yyyy-MM-dd
	 * 	<br>yyyy/MM/dd
	 * 	<br>yyyyMMdd
	 * 	
	 * 	@author Pan
	 * 	@param 	<T>			数据类型
	 * 	@param 	list		对象list
	 * 	@param 	fieldName	需要排序的字段
	 * 	@param 	sort		desc或 asc的字符串
	 */
	public static <T> void sortTime(List<T> list, String fieldName, Sort sort) {
		if (CollUtils.isEmpty(list)) {
			return ;
		}
		
		//	时分秒最大长度
		final int maxYmdSize = 10;
		final String timeTag = " 00:00:00";
		Collections.sort(list, (o1, o2) -> {
			List<String> listCompare = CollComparator.getCompareObj(CollComparator.setCompareList(o1, o2), fieldName);
			
			if (CollUtils.isEmpty(listCompare)) {
				return -1;
			}
			String startTime = listCompare.get(0);
			String endTime = listCompare.get(1);
			
			int startTimeLen = startTime.length();
			int endTimeLen = endTime.length();
			
			if (startTimeLen > maxYmdSize && endTimeLen > maxYmdSize) {
				return DateUtils.dateTimeCompareToByMillis(startTime, endTime);
			}
			
			if (startTimeLen <= maxYmdSize && startTimeLen != endTimeLen) {
				return DateUtils.dateTimeCompareToByMillis(startTime.concat(timeTag), endTime);
			}
			
			if (endTimeLen <= maxYmdSize && endTimeLen != startTimeLen) {
				return DateUtils.dateTimeCompareToByMillis(startTime, endTime.concat(timeTag));
			}
			
			return DateUtils.dateCompareTo(startTime, endTime);
		});
		sortType(list, sort);
	}
	
	/**	
	 * 	排序类型
	 * 	
	 * 	@author Pan
	 * 	@param 	<T>			数据类型
	 * 	@param 	list		集合
	 * 	@param 	sort		排序类型
	 */
	private static <T> void sortType(List<T> list, Sort sort) {
		if (Sort.DESC.equals(sort)) {
			reverse(list);
		}
	}
	
	/**
	 * 	获取数值和
	 * 	
	 * 	@author Pan
	 * 	@param 	<E>		元素
	 * 	@param 	list	集合
	 * 	@return	E
	 */
	public static <E> E sum(List<E> list) {
		if (isEmpty(list)) {
			return null;
		}
		return calculation(list, CalculationTypeEnum.SUM);
	}
	
	/**
	 * 	获取数值和
	 * 	
	 * 	@author Pan
	 * 	@param 	<E>			元素
	 * 	@param 	list		集合
	 * 	@param 	fieldName	字段名称
	 * 	@return	Object
	 */
	public static <E> Object sum(List<E> list, String fieldName) {
		if (ValidParam.isEmpty(list)) {
			return Empty.list();
		}
		return sum(ReflectionUtils.getFieldValue(list, fieldName));
	} 
	
	/**
	 * 	List转换字符串 
	 * 	<br>并且附带自定义分隔符
	 * 
	 * 	@author Pan
	 * 	@param 	<T>			数据类型
	 * 	@param 	list		集合
	 * 	@param 	tag			分隔符标识
	 * 	@return	String
	 */
	public static <T> String toStr(List<T> list, String tag) {
		if (isEmpty(list)) {
			return Empty.str();
		}
		
		StringBuilder builder = StringUtils.createBuilder();
		
		for (int i = 0, len = list.size(); i < len; i++) {
			if ((i + 1) == len) {
				builder.append(list.get(i));
				break; 
			}
			builder.append(list.get(i)).append(tag);
		}
		return builder.toString();
	}
	
	/**	
	 * 	并集-不修改原有对象(返回新对象)
	 * 	<br> e1和e2集合所有的元素合并在一起组成的集合
	 * 	<br> {@code e1 = {a}, e2 = {b}, e1∪e2 = {a, b} }
	 * 
	 * 	@author Pan
	 * 	@param 	<E>		元素
	 * 	@param 	e1		集合1
	 * 	@param 	e2		集合2
	 * 	@return	Set
	 */
	public static <E> Set<E> union(List<E> e1, List<E> e2) {
		if (isEmpty(e1) && isEmpty(e2)) {
			return Empty.set();
		}
		return union(newHashSet(e1), newHashSet(e2));
	}
	
	/**	
	 * 	并集-不修改原有对象(返回新对象)
	 * 	<br> e1和e2集合所有的元素合并在一起组成的集合
	 * 	<br>{@code e1 = {a, b, c}, e2 = {c, d, e}, e1∪e2 = {a, b, c, d, e} }
	 * 
	 * 	@author Pan
	 * 	@param 	<E>		元素
	 * 	@param 	e1		集合1
	 * 	@param 	e2		集合2
	 * 	@return	Set
	 */
	public static <E> Set<E> union(Set<E> e1, Set<E> e2) {
		if (isEmpty(e1) && isEmpty(e2)) {
			return Empty.set();
		}
		return addAll(newHashSet(e1), e2);
	}
}	
